﻿using Common.Communal;
using ERP.Domain.Scheduling;
using MediatR;
using Scheduling.Api.Read.Application.Command.ScheduleCommand;
using Scheduling.Api.Read.Application.DTO;
using SqlSugar;

namespace Scheduling.Api.Read.Application.CommandHandlers.ScheduleHandler
{
    public class ScheduleCreateCommandHandler : IRequestHandler<ScheduleCreateCommand, ApiResult<List<ScheduleWithDetailsDTO>>>
    {
        public ScheduleCreateCommandHandler(ISqlSugarClient sqlSugar)
        {
            SqlSugar = sqlSugar;
        }

        public ISqlSugarClient SqlSugar { get; }

        public Task<ApiResult<List<ScheduleWithDetailsDTO>>> Handle(ScheduleCreateCommand request, CancellationToken cancellationToken)
        {
            ApiResult<List<ScheduleWithDetailsDTO>> result = new ApiResult<List<ScheduleWithDetailsDTO>>
            {
                Code = EnumCode.Ok,
                Message = "排班信息查询成功"
            };

            // 多表联查：Schedule -> Team -> TeamType, Shift, Calendar, ScheduleDetail
            var query = SqlSugar.Queryable<Schedule>()
                .LeftJoin<Team>((s, t) => s.TeamId == t.TeamId)
                .LeftJoin<TeamType>((s, t, tt) => t.TeamTypeId == tt.TeamTypeId)
                .LeftJoin<Shift>((s, t, tt, sh) => s.ShiftId == sh.ShiftId)
                .LeftJoin<Calendar>((s, t, tt, sh, c) => s.CalenDarId == c.CalendarId)
                .LeftJoin<ScheduleDetail>((s, t, tt, sh, c, sd) => s.ScheduleId == sd.ScheduleId)
                .Where((s, t, tt, sh, c, sd) => 
                    s.IsDelete == false && 
                    (t.IsDelete == false || t.IsDelete == null) &&
                    (tt.IsDelete == false || tt.IsDelete == null) &&
                    (sh.IsDelete == false || sh.IsDelete == null) &&
                    (c.IsDelete == false || c.IsDelete == null) &&
                    (sd.IsDelete == false || sd.IsDelete == null));

            // 应用筛选条件
            if (request.TeamId.HasValue)
                query = query.Where((s, t, tt, sh, c, sd) => s.TeamId == request.TeamId.Value);

            if (request.ShiftId.HasValue)
                query = query.Where((s, t, tt, sh, c, sd) => s.ShiftId == request.ShiftId.Value);

            if (request.StartDate.HasValue)
                query = query.Where((s, t, tt, sh, c, sd) => s.ScheduleDate >= request.StartDate.Value);

            if (request.EndDate.HasValue)
                query = query.Where((s, t, tt, sh, c, sd) => s.ScheduleDate <= request.EndDate.Value);

            if (request.IsUrgentSchedule.HasValue)
                query = query.Where((s, t, tt, sh, c, sd) => s.IsUrgentSchedule == request.IsUrgentSchedule.Value);

            if (request.IsUrgentOrder.HasValue)
                query = query.Where((s, t, tt, sh, c, sd) => s.IsUrgentOrder == request.IsUrgentOrder.Value);

            if (request.IsNightShift.HasValue)
                query = query.Where((s, t, tt, sh, c, sd) => sh.IsNightShift == request.IsNightShift.Value);

            if (!string.IsNullOrWhiteSpace(request.TeamNameKeyword))
                query = query.Where((s, t, tt, sh, c, sd) => t.TeamName.Contains(request.TeamNameKeyword));

            if (!string.IsNullOrWhiteSpace(request.ShiftNameKeyword))
                query = query.Where((s, t, tt, sh, c, sd) => sh.ShiftName.Contains(request.ShiftNameKeyword));

            // 选择所需字段并映射到DTO
            var list = query.Select<ScheduleWithDetailsDTO>(@"
                s.ScheduleId, s.ScheduleDate, s.IsUrgentSchedule, s.IsUrgentOrder,
                s.TeamId, t.TeamName, t.TeamLeader, tt.TeamTypeName, tt.TeamTypeCode,
                s.ShiftId, sh.ShiftName, sh.StartTime, sh.EndTime, sh.IsNightShift, 
                sh.DisplayColor, sh.OvertimeRate, sh.Breakduration, sh.ShiftStatus,
                s.CalenDarId as CalendarId, c.CalendarDate, c.IsWorkDay, c.IsUrgentWorkday, 
                c.UrgentReason, c.HoildayType,
                sd.DetailId, sd.ActualStatus, sd.Remarks")
                .OrderBy("s.ScheduleDate, t.TeamName, sh.ShiftName")
                .ToList();

            result.Data = list;
            return Task.FromResult(result);
        }
    }
}
